/*
 * @(#) WorkOrderService.java 2013-6-11 上午11:31:32
 *
 * Copyright 2013 Rockwell Automation, Inc. All rights reserved.
 * Rockwell Automation PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */package com.osi.mes.pm;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Vector;

import pnuts.lang.Context;

import com.datasweep.compatibility.client.BillOfMaterials;
import com.datasweep.compatibility.client.BomItem;
import com.datasweep.compatibility.client.Filter;
import com.datasweep.compatibility.client.Lot;
import com.datasweep.compatibility.client.Order;
import com.datasweep.compatibility.client.OrderItem;
import com.datasweep.compatibility.client.OrderItemFilter;
import com.datasweep.compatibility.client.Part;
import com.datasweep.compatibility.client.Queue;
import com.datasweep.compatibility.client.Response;
import com.datasweep.compatibility.client.Route;
import com.datasweep.compatibility.client.Step;
import com.datasweep.compatibility.client.UDADefinition;
import com.datasweep.compatibility.manager.OrderManager;
import com.datasweep.compatibility.manager.ServerImpl;
import com.datasweep.compatibility.pnuts.Functions;
import com.datasweep.compatibility.ui.Time;
import com.datasweep.plantops.common.constants.filtering.IFilterComparisonOperators;
import com.datasweep.plantops.common.constants.filtering.IWorkOrderItemFilterAttributes;
import com.osi.mes.base.BaseService;
import com.osi.mes.constants.IOrderItemConstants;
import com.osi.mes.utils.NumberUtils;
import com.osi.mes.utils.StringUtils;

public class WorkOrderService extends BaseService implements IOrderItemConstants
{

	public WorkOrderService(Context context)
	{
		super(context);
	}

	public WorkOrderService(Functions functions)
	{
		super(functions);
	}

	/**
	 * 删除工单
	 * 
	 * @param orderNumber
	 *            工单号
	 * @return Response
	 */
	public Response removeOrder(String orderNumber)
	{
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		Response response = order.remove(
			getFunctions().getDBTime(), null);
		return response;
	}

	/**
	 * 根据查询条件查询工单信息
	 * 
	 * @param orderNumber
	 *            工单号
	 * @param orderType
	 *            工单类型
	 * @param partNumber
	 *            产品名称
	 * @param productionLineName
	 *            生产线
	 * @param orderState
	 *            工单状态
	 * @param plannedStartTimeBegin
	 *            计划开始时间
	 * @param plannedStartTimeEnd
	 *            计划开始时间
	 * @return Vector 包含了符合条件的OrderItem
	 */
	public Vector queryOrder(String orderNumber, String orderType, String partNumber,
		String productionLineName, String orderState, Time plannedStartTimeBegin,
		Time plannedStartTimeEnd)
	{
		Vector orderItems = new Vector();
		ServerImpl serverImpl = getFunctions().getCurrentUser().getServerImpl();
		OrderItemFilter orderItemFilter = new OrderItemFilter(serverImpl);
		if (StringUtils.isNotNull(orderNumber))
		{
			orderItemFilter.addSearchBy(
				IWorkOrderItemFilterAttributes.NAME, IFilterComparisonOperators.CONTAINING,
				orderNumber);
		}
		if (StringUtils.isNotNull(orderType))
		{
			String uda = UDADefinition.getUDAKeyFromIndex(
				OrderItem.TOTAL_UDA_COLUMN, 0);
			orderItemFilter.forUdaEqualTo(
				uda, orderType);
		}
		if (StringUtils.isNotNull(partNumber))
		{
			orderItemFilter.addSearchBy(
				IWorkOrderItemFilterAttributes.PART_NUMBER, IFilterComparisonOperators.CONTAINING,
				partNumber);
		}
		if (StringUtils.isNotNull(productionLineName))
		{
			orderItemFilter.addSearchBy(
				IWorkOrderItemFilterAttributes.PLANNED_LINE, IFilterComparisonOperators.CONTAINING,
				productionLineName);
		}
		if (StringUtils.isNotNull(orderState))
		{
			orderItemFilter.addSearchBy(
				IWorkOrderItemFilterAttributes.ORDER_STATE, IFilterComparisonOperators.EQUAL_TO,
				orderState);
		}
		if (plannedStartTimeBegin != null)
		{
			orderItemFilter.addSearchBy(
				IWorkOrderItemFilterAttributes.PLANNED_START_TIME,
				IFilterComparisonOperators.GREATER_THAN_EQUAL_TO, plannedStartTimeBegin);
		}
		if (plannedStartTimeEnd != null)
		{
			orderItemFilter.addSearchBy(
				IWorkOrderItemFilterAttributes.PLANNED_START_TIME,
				IFilterComparisonOperators.LESS_THAN_EQUAL_TO, plannedStartTimeEnd);
		}
		OrderManager orderManager = serverImpl.getOrderManager();
		Method method;
		try
		{
			method = orderManager.getClass().getDeclaredMethod(
				"getOrderItems", Filter.class);

			method.setAccessible(true);
			orderItems = (Vector) method.invoke(
				orderManager, orderItemFilter);
		}
		catch (Exception e)
		{
			// logError(e, module, position);
		}
		return orderItems;
	}

	/**
	 * 确认物料数量
	 * 
	 * @param orderItem
	 *            工单号
	 * @param map
	 *            每种物料对应的真实数量
	 * @return Response
	 */
	public Response confirmBomItemsQty(String orderItem, HashMap<String, BigDecimal> map)
	{
		Response response = null;
		try
		{
			Lot lot = getFunctions().getLotByName(
				orderItem);
			BillOfMaterials bom = lot.getBillOfMaterials();
			Vector bomItems = bom.getBomItems();
			for (int i = 0; i < bomItems.size(); i++)
			{
				BomItem bomItem = (BomItem) bomItems.get(i);
				BigDecimal realQty = map.get(bomItem.getBomItemName());
				bomItem.setQuantity(realQty);
			}
			response = bom.save();
		}
		catch (Exception e)
		{
			response = createErrorResponse(e);
		}
		return response;
	}

	/**
	 * 发布工单 1.将备料信息发送至WMS 2.将工单状态修改为发布 3.将该工单信息发送至ERP
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response publishOrder(String orderNumber)
	{
		// 将备料信息发送至WMS
		Lot lot = getFunctions().getLotByName(
			orderNumber);
		BillOfMaterials bom = lot.getBillOfMaterials();
		Vector bomItems = bom.getBomItems();
		// TODO

		// 将工单状态改为发布
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_PUBLISHED);
		order.setOrderState(ORDER_STATE_PUBLISHED);
		Response response = order.save();

		// 将工单发送至SAP
		// TODO

		return response;
	}

	/**
	 * 启动工单
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response startOrder(String orderNumber)
	{
		// 将工单状态改为启动
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_STARTED);
		order.setOrderState(ORDER_STATE_STARTED);
		Response response = order.save();
		return response;
	}

	/**
	 * 工单停止生产 1.将工单状态修改为停止生产 2.将该工单信息发送至ERP
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response stopProduction(String orderNumber)
	{
		// 将工单状态改为停止生产
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_STOP_PRODUCTION);
		order.setOrderState(ORDER_STATE_STOP_PRODUCTION);
		Response response = order.save();

		// 将工单发送至SAP
		// TODO

		return response;
	}

	/**
	 * 工单取消 1.将工单状态修改为取消 2.将该工单信息发送至ERP
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response cancelOrder(String orderNumber)
	{
		// 将工单状态改为取消
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_CANCELLED);
		order.setOrderState(ORDER_STATE_CANCELLED);
		Response response = order.save();

		// 将工单发送至SAP
		// TODO

		return response;
	}

	/**
	 * 工单恢复生产 1.将工单状态修改为启动 2.将该工单信息发送至ERP
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response recoverOrder(String orderNumber)
	{
		// 将工单状态恢复为启动
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_STARTED);
		order.setOrderState(ORDER_STATE_STARTED);
		Response response = order.save();

		// 将工单发送至SAP
		// TODO

		return response;
	}

	/**
	 * 工单停止投料 1.将工单状态修改为停止投料 2.将该工单信息发送至ERP
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response stopConsumption(String orderNumber)
	{
		// 将工单状态改为停止投料
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_STOP_CONSUMPTION);
		order.setOrderState(ORDER_STATE_STOP_CONSUMPTION);
		Response response = order.save();

		// 将工单发送至SAP
		// TODO

		return response;
	}

	/**
	 * 工单关闭 1.将工单状态修改为关闭 2.将该工单信息发送至ERP
	 * 
	 * @param orderNumber
	 * @return Response
	 */
	public Response closeOrder(String orderNumber)
	{
		// 将工单状态改为关闭
		Order order = getFunctions().getWorkOrder(
			orderNumber);
		OrderItem orderItem = order.getOrderItem(orderNumber);
		orderItem.setOrderState(ORDER_STATE_CLOSED);
		order.setOrderState(ORDER_STATE_CLOSED);
		Response response = order.save();

		// 将工单发送至SAP
		// TODO

		return response;
	}

	private String generateOrderNumber(String productionLineName, String partNumber)
	{
		Time time = getFunctions().getDBTime();
		int year = time.getYear();
		int month = time.getMonth();
		int day = time.getDay();
		// ORD20130612P110127
		return ORDER_NUMBER_SUFFIX + year + NumberUtils.toNumString(month)
			+ NumberUtils.toNumString(day) + productionLineName + partNumber;
	}

}
